const toString = Object.prototype.toString
/**
 * Gets the `toStringTag` of `value`.
 *
 * @private
 * @param {*} value The value to query.
 * @returns {string} Returns the `toStringTag`.
 */
const getTag = function(value) {
  if (value == null) {
    return value === undefined ? '[object Undefined]' : '[object Null]'
  }
  return toString.call(value)
}

const isObjectLike = function(value) {
  return typeof value === 'object' && value !== null
}

export class OUtils {
  static {

  }

  static isObject(value) {
    const type = typeof value
    return value != null && (type === 'object' || type === 'function')
  }

  static isNumberPrimitive(value) {
    return (
      typeof value === 'number' || (isObjectLike(value) && getTag(value) === '[object Number]')
    )
  }

  static isString(value) {
    const type = typeof value
    return (
      type === 'string' ||
      (type === 'object' &&
        value != null &&
        !Array.isArray(value) &&
        getTag(value) === '[object String]')
    )
  }

  static isFunction(value) {
    return typeof value === 'function'
  }

  static isBoolean(value) {
    return (
      value === true ||
      value === false ||
      (isObjectLike(value) && getTag(value) === '[object Boolean]')
    )
  }

  static isArguments(value) {
    return isObjectLike(value) && getTag(value) === '[object Arguments]'
  }

  static mergeObject(o1 = {}, o2 = {}) {
    let res = Object.assign({}, o1, o2)

    return res
  }
}
